package open.intellijboy.framework.core.model;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
import lombok.Data;

import java.io.Serial;
import java.io.Serializable;

/**
 * 分页请求参数
 *
 * @author System
 * @version 1.0.0
 * @since 2024-01-01
 */
@Data
@Schema(description = "分页请求参数")
public class PageRequest implements Serializable {

    @Serial
    private static final long serialVersionUID = 1L;

    /**
     * 默认页码
     */
    private static final int DEFAULT_PAGE_NUM = 1;

    /**
     * 默认页大小
     */
    private static final int DEFAULT_PAGE_SIZE = 10;

    /**
     * 最大页大小
     */
    private static final int MAX_PAGE_SIZE = 100;

    /**
     * 页码（从1开始）
     */
    @Schema(description = "页码，从1开始", example = "1", minimum = "1")
    @Min(value = 1, message = "页码不能小于1")
    private Integer pageNum = DEFAULT_PAGE_NUM;

    /**
     * 页大小
     */
    @Schema(description = "页大小", example = "10", minimum = "1", maximum = "100")
    @Min(value = 1, message = "页大小不能小于1")
    @Max(value = MAX_PAGE_SIZE, message = "页大小不能超过100")
    private Integer pageSize = DEFAULT_PAGE_SIZE;

    /**
     * 排序字段
     */
    @Schema(description = "排序字段", example = "createTime")
    private String orderBy;

    /**
     * 排序方向（ASC/DESC）
     */
    @Schema(description = "排序方向", example = "DESC", allowableValues = {"ASC", "DESC"})
    private String orderDirection = "DESC";

    /**
     * 获取偏移量（用于数据库查询）
     *
     * @return 偏移量
     */
    public int getOffset() {
        return (pageNum - 1) * pageSize;
    }

    /**
     * 获取限制数量（用于数据库查询）
     *
     * @return 限制数量
     */
    public int getLimit() {
        return pageSize;
    }

    /**
     * 设置页码
     *
     * @param pageNum 页码
     */
    public void setPageNum(Integer pageNum) {
        this.pageNum = pageNum == null || pageNum < 1 ? DEFAULT_PAGE_NUM : pageNum;
    }

    /**
     * 设置页大小
     *
     * @param pageSize 页大小
     */
    public void setPageSize(Integer pageSize) {
        if (pageSize == null || pageSize < 1) {
            this.pageSize = DEFAULT_PAGE_SIZE;
        } else if (pageSize > MAX_PAGE_SIZE) {
            this.pageSize = MAX_PAGE_SIZE;
        } else {
            this.pageSize = pageSize;
        }
    }

    /**
     * 设置排序方向
     *
     * @param orderDirection 排序方向
     */
    public void setOrderDirection(String orderDirection) {
        if (orderDirection != null &&
            ("ASC".equalsIgnoreCase(orderDirection) || "DESC".equalsIgnoreCase(orderDirection))) {
            this.orderDirection = orderDirection.toUpperCase();
        } else {
            this.orderDirection = "DESC";
        }
    }

    /**
     * 创建默认分页请求
     *
     * @return PageRequest
     */
    public static PageRequest of() {
        return new PageRequest();
    }

    /**
     * 创建分页请求
     *
     * @param pageNum  页码
     * @param pageSize 页大小
     * @return PageRequest
     */
    public static PageRequest of(Integer pageNum, Integer pageSize) {
        PageRequest pageRequest = new PageRequest();
        pageRequest.setPageNum(pageNum);
        pageRequest.setPageSize(pageSize);
        return pageRequest;
    }

    /**
     * 创建分页请求
     *
     * @param pageNum        页码
     * @param pageSize       页大小
     * @param orderBy        排序字段
     * @param orderDirection 排序方向
     * @return PageRequest
     */
    public static PageRequest of(Integer pageNum, Integer pageSize, String orderBy, String orderDirection) {
        PageRequest pageRequest = new PageRequest();
        pageRequest.setPageNum(pageNum);
        pageRequest.setPageSize(pageSize);
        pageRequest.setOrderBy(orderBy);
        pageRequest.setOrderDirection(orderDirection);
        return pageRequest;
    }
}